<?php

namespace App\Http\Controllers\Admin;

use App\Exports\AgentExport;
use App\Exports\PartnerExport;
use App\Http\Controllers\Controller;
use App\Models\Agent;
use App\Models\IndicatorsDailySummary;
use App\Models\Partner;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;

class PartnerController extends Controller
{
    public function store(Request $request)
    {
        $agentPartner = null;
        \DB::transaction(function () use ($request, &$agentPartner) {
            $agentPartner = Agent::query()->findOrFail($request->get('agent'));
            // 是否之前有被删除的身份
            $deletedPartner = $agentPartner->partnerIdentity()->withTrashed()->first();
            if ($deletedPartner) {
                // 有就直接恢复
                $deletedPartner->fill(['created_at' => Carbon::now()])->restore();
            } else {
                // 创建
                $agentPartner->partnerIdentity()->updateOrCreate(
                    ['agent_id' => $request->get('agent')],
                    ['level' => $request->get('level')]
                );
            }

            // 成为合伙人后 代理商所属合伙人变为自己
            $agentPartner->update([
                'affiliated_partner' => $agentPartner['id']
            ]);

            // (没有合伙人身份的)下级 的所属合伙人 变为 当前代理商
            $changeFun = function ($agentIds) use (&$agentPartner, &$changeFun) {
                $subordinateAgentIds = Agent::query()
                    ->whereIn('direct_inviter', $agentIds)
                    ->whereDoesntHave('partnerIdentity')
                    ->pluck('id');
                if ($subordinateAgentIds->isEmpty()) {
                    return;
                }
                Agent::query()
                    ->whereIn('id', $subordinateAgentIds)
                    ->update(['affiliated_partner' => $agentPartner['id']]);
                $changeFun($subordinateAgentIds);
            };
            $changeFun([$agentPartner['id']]);
        });

        activity()
            ->on($agentPartner)
            ->by(\Auth::user())
            ->withProperty('ip', app('request')->ip())
            ->log(sprintf('设置 %s (%s) 为 %s', $agentPartner['name'] ?? '', $agentPartner['id'] ?? '', Partner::LEVEL_MAP[$request->get('level')] ?? ''));

        return $this->response->created(null);
    }

    public function delete($id)
    {
        $partner = null;
        \DB::transaction(function () use ($id, &$partner) {
            $partner = Partner::query()->with(['agent'])->findOrFail($id);

            // 合伙人下级 删除对应的 所属合伙人 为空
            Agent::query()->where('affiliated_partner', $partner->agent['id'])->update(['affiliated_partner' => 0]);
            // 删除
            $partner->delete();
        });

        activity()
            ->on($partner->agent)
            ->by(\Auth::user())
            ->withProperty('ip', app('request')->ip())
            ->log(sprintf('删除 %s (%s) %s身份', $partner->agent['name'] ?? '', $partner->agent['id'] ?? '', Partner::LEVEL_MAP[$partner['level'] ?? 0] ?? ''));

        return $this->response->noContent();
    }

    public function list(Request $request)
    {
        if ($request->has('export')) {
            return (new PartnerExport($request))->download(sprintf('合伙人(%s).xls', Carbon::now()->format('YmdHisu')));
        }

        return $this->response->array(
            Agent::query()
                ->with('partnerIdentity')
                ->whereHas('partnerIdentity', function (Builder $builder) use ($request) {
                    $builder
                        ->when($request->get('level'), function (Builder $builder, $level) {
                            $builder->where('level', $level);
                        })
                        ->when($request->get('created_at_begin'), function (Builder $builder, $createdAtBegin) {
                            $builder->where('created_at', '>=', $createdAtBegin);
                        })
                        ->when($request->get('created_at_end'), function (Builder $builder, $createdAtEnd) {
                            $builder->where('created_at', '<=', Carbon::parse($createdAtEnd)->endOfDay());
                        });
                })
                ->when($request->get('name'), function (Builder $builder, $name) {
                    $builder->where('name', 'like', "%$name%");
                })
                ->when($request->get('phone'), function (Builder $builder, $phone) {
                    $builder->where('phone', 'like', "%$phone%");
                })
                ->when(
                    $request->get('performance_range_begin') && $request->get('performance_range_end'),
                    function (Builder $builder) use ($request) {
                        $begin = $request->get('performance_range_begin');
                        $end = $request->get('performance_range_end');

                        $builder
                            ->select([
                                'agents.id', 'agents.name', 'agents.phone',
                            ])
                            ->selectSub(
                                // 业绩按日期范围汇总
                                \DB::table('indicators_daily_summary')
                                    ->selectRaw('sum(performance_summary)')
                                    ->whereBetween('day', [$begin, $end])
                                    ->where('type', IndicatorsDailySummary::TYPE_PARTNER)
                                    ->whereRaw('agent_id = agents.id'),
                                'performance'
                            )
                            ->selectSub(
                                // 佣金按日期范围汇总
                                \DB::table('indicators_daily_summary')
                                    ->selectRaw('sum(commission_summary)')
                                    ->whereBetween('day', [$begin, $end])
                                    ->where('type', IndicatorsDailySummary::TYPE_PARTNER)
                                    ->whereRaw('agent_id = agents.id'),
                                'commission'
                            )
                            ->selectSub(
                                // 奖励按日期范围汇总
                                \DB::table('indicators_daily_summary')
                                    ->selectRaw('sum(reward_summary)')
                                    ->whereBetween('day', [$begin, $end])
                                    ->where('type', IndicatorsDailySummary::TYPE_PARTNER)
                                    ->whereRaw('agent_id = agents.id'),
                                'reward'
                            );
                    },
                    function (Builder $builder) {
                        $builder->select(['agents.id', 'agents.name', 'agents.phone']);
                    })
                ->paginate());
    }
}
